﻿using MongoDB.Driver;
using Sustainalytics.DataLayer;
using Sustainalytics.Entities;
using Sustainalytics.Entities.ConnectionStrings;
using Sustainalytics.Synchronization.Interface;
using Sustainalytics.Utils.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;

// Sustainalytics.PregenerateScreeningReports: ISyncStep
// Orchestrator
// 1. start VM instances, base on AMI and config, ip(ID) as key of the instance
// 2.1 create job to create maximal report per type (with all distinct companies from universe company collection)
//     per each instance
// 2.2 create jobs per each "key" instance base on account and report type
// distribute workload based on company number by account, ajusted by report type
//
// Sustainalytics.PregenerateScreeningReports.Service (WindowsService)
// Executor
// 1. wait after my jobs, first job is maximal report
// 1.0 cache the generated maximal report and download the rest
// 1.1 wait after and poll the maximal report to execute account jobs
// 2. rendered report is uploaded to S3

namespace Sustainalytics.PregenerateScreeningReports
{
    public class PregenerateStandardReportsSyncStep : ISyncStep
    {
        public SyncStepOrder ExecutionOrder => SyncStepOrder.PregenerateScreeningReports;

        public SyncContext Start(SyncContext syncContext)
        {
            var mainMachine = SettingsHelper.Read<string>("PSR_MainMachine", "i-09b5a947bc375b0bc");
            var machinesText = SettingsHelper.Read<string>("PSR_Machines", "");
            var ttl = SettingsHelper.Read<int>("PSR_TTLMinutes", 55);

            if (string.IsNullOrEmpty(mainMachine))
                throw new ApplicationException("PSR_MainMachine is null or empty");

            var machines = machinesText.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var allMachines = machines.Select(x => x.Trim())
                                        .Union(new string[] { mainMachine.Trim() })
                                        .Distinct();

            // collect standard reports
            var filtersColl = MongoDatabaseFactory.GetDatabase(syncContext.GAConnectionStrings["ClientPlatform"]).GetCollection<Filter>();
            var filters = filtersColl.Find(x => x.Type == FilterType.Standard && x.Status == FilterStatus.Active)
                                     .Project(Builders<Filter>.Projection.Include(x => x.Id).Include(x => x.Name))
                                     .As<Filter>()
                                     .ToList();
            var reportIds = filters.Select(x => x.Id);

            var dic = new Dictionary<ConnectionStringType, string>();
            dic[ConnectionStringType.ClientPlatform] = syncContext.GAConnectionStrings["ClientPlatform"];
            dic[ConnectionStringType.ClientUniverses] = syncContext.GAConnectionStrings["ClientUniverses"];
            dic[ConnectionStringType.ClientDW] = syncContext.GAConnectionStrings["ClientDW"];
            dic[ConnectionStringType.ScreeningDW] = syncContext.GAConnectionStrings["ScreeningDW"];
            var session = ScreeningReportsDistributionLogic.CreateSession(mainMachine, allMachines, reportIds, ttl, dic);

            var sessionColl = MongoDatabaseFactory.GetDatabase(syncContext.GAConnectionStrings["ClientDWMaster"]).GetCollection<ScreeningToolReportDistributionSession>();
            sessionColl.InsertOne(session);

            // remove s3 files
            AWSHelper.CleanS3Storage(syncContext.GAConnectionStrings["ScreeningDW"], syncContext.GAConnectionStrings["ClientPlatform"]);

            // start main machine
            AWSHelper.StartAWSInstances(new[] { mainMachine }, syncContext.Log);

            syncContext.Status = SyncOperationStatus.Succeeded;
            return syncContext;
        }
    }
}
